import {KeyboardTypeOptions, StyleSheet, Text, TextInput, TouchableOpacity, View} from "react-native"
import {Controller, useFieldArray, useFormContext} from "react-hook-form";
import React, {JSX, useState} from "react";
import {Picker} from "@react-native-picker/picker";
import DateTimePicker, {DateTimePickerEvent} from "@react-native-community/datetimepicker";
import dayjs from "dayjs";
import {Icon} from "./Icon";
import {RegionSelector} from "./RegionSelector.tsx";
import {Button, CheckBox} from "@rneui/themed";
import {CheckBoxIcon} from "@rneui/base/dist/CheckBox/components/CheckBoxIcon";

/**
 * 通用输入框组件的属性定义
 */
interface InputProps {
    /**
     * 在 react-hook-form 中注册的字段名称。这是必填项。
     * @example 'username'
     * @example 'user.firstName'
     */
    name: string;
    /**
     * 显示在输入框上方的标签文本。这是必填项。
     */
    label: string;
    /**
     * react-hook-form 的验证规则对象。可选。
     * 用于定义字段的验证逻辑，如必填、最小长度、正则表达式等。
     * @see https://react-hook-form.com/api/useform/register
     * @example
     * {
     *   required: '此字段为必填项',
     *   minLength: { value: 4, message: '长度不能少于4个字符' },
     *   pattern: { value: /^[A-Za-z]+$/i, message: '只能包含英文字母' }
     * }
     */
    rules?: object;
    /**
     * 输入框的占位文本。可选。
     * 如果未提供，则占位符将是一个空字符串。
     */
    placeholder?: string;
    /**
     * 指定要显示的键盘类型，以优化用户输入体验。可选。
     * 如果未提供，将默认为 'default'。
     * @see https://reactnative.dev/docs/textinput#keyboardtype
     * @type {KeyboardTypeOptions}
     * @example 'numeric'         // 纯数字键盘
     * @example 'email-address'   // 带有 @ 和 . 符号的邮箱键盘
     * @example 'phone-pad'       // 电话拨号键盘
     */
    keyboardType?: KeyboardTypeOptions;
}

/**
 * 通用的样式
 */
const formStyles = StyleSheet.create({
    label: {
        fontSize: 16,
        fontWeight: '600',
        marginTop: 22,
        marginBottom: 4,
    },
    error: {
        color: 'red',
        fontSize: 12,
        marginTop: 2,
    }
})

const inputStyles = StyleSheet.create({
    input: {
        borderWidth: StyleSheet.hairlineWidth,
        borderColor: '#888',
        borderRadius: 8,
        paddingHorizontal: 8,
        fontSize: 16,
        height: 55,
        justifyContent: 'center',
        textAlignVertical: 'center',
    },
});

const multilineInputStyles = StyleSheet.create({
    input: {
        borderWidth: StyleSheet.hairlineWidth,
        borderColor: '#888',
        borderRadius: 8,
        paddingHorizontal: 8,
        fontSize: 16,
        height: 150,
        textAlignVertical: 'top'
    },
});

const pickerStyles = StyleSheet.create({
    pickerWrapper: {
        borderWidth: StyleSheet.hairlineWidth,
        borderColor: '#888',
        borderRadius: 9,
        marginBottom: 8,
        height: 60,
    },
    picker: {
        height: 54,
    },
    readonlyText: {
        fontSize: 16,
        paddingHorizontal: 8,
        lineHeight: 54, // 垂直居中
        color: '#333'
    }
})

const chooserStyles = StyleSheet.create({
    radioGroup: {
        marginVertical: 4,
    },
    radioRow: {
        flexDirection: 'row',
        alignItems: 'center',
        marginVertical: 10,
    },
    radio: {
        height: 20,
        width: 20,
        borderWidth: 1,
        marginRight: 8,
        borderColor: '#666',
    },
    radioChecked: {
        backgroundColor: '#007AFF',
    },
})

const datePickerStyles = StyleSheet.create({
    formItemContainer: {
        width: '100%',
    },
    label: {
        fontSize: 16,
        fontWeight: '600',
        marginTop: 22,
        marginBottom: 4,
    },
    dateButton: {
        borderWidth: 1,
        borderColor: '#ddd',
        borderRadius: 8,
        padding: 12,
        marginBottom: 8,
        minHeight: 50,
        justifyContent: 'center',
    },
    dateButtonText: {
        fontSize: 16,
        lineHeight: 22,
        color: '#333',
    },
    errorText: {
        color: 'red',
        fontSize: 12,
        marginTop: 2,
    },
});

/**
 * 一个与 react-hook-form 集成的通用输入框组件。
 *
 * 该组件必须在 `<FormProvider>` 的子组件中使用。
 * 它会自动处理字段注册、值更新和错误显示。
 *
 * @param {InputProps} props - 组件的属性
 * @returns {JSX.Element}
 *
 * @example
 * <FormProvider {...methods}>
 *   <FormItems.Input
 *     name="username"
 *     label="用户名"
 *     rules={{ required: '用户名是必填的' }}
 *   />
 * </FormProvider>
 */
export const Input = ({name, label, rules, placeholder, keyboardType}: InputProps): JSX.Element => {
    const {control, formState: {errors}} = useFormContext();

    return (
        <View style={{width: '100%'}}>
            <Text style={formStyles.label}>{label}</Text>
            <Controller
                control={control}
                name={name}
                rules={rules}
                render={({field: {onChange, value}}) => (
                    <TextInput
                        style={inputStyles.input}
                        placeholder={placeholder || ""}
                        value={value}
                        onChangeText={onChange}
                        keyboardType={keyboardType || "default"}
                    />
                )}
            />
            {errors[name] && <Text style={formStyles.error}>{(errors[name] as any).message}</Text>}
        </View>
    )
};

export const MultilineInput = ({name, label, rules, placeholder, keyboardType}: InputProps): JSX.Element => {
    const {control, formState: {errors}} = useFormContext();

    return (
        <View style={{width: '100%'}}>
            <Text style={formStyles.label}>{label}</Text>
            <Controller
                control={control}
                name={name}
                rules={rules}
                render={({field: {onChange, value}}) => (
                    <TextInput
                        style={multilineInputStyles.input}
                        placeholder={placeholder || ""}
                        value={value}
                        multiline
                        onChangeText={onChange}
                        keyboardType={keyboardType || "default"}
                    />
                )}
            />
            {errors[name] && <Text style={formStyles.error}>{(errors[name] as any).message}</Text>}
        </View>
    )
}

interface PickProps {
    name: string,
    label: string,
    rules?: object,
    placeholder: string,
    units: any[],
    readonly?: boolean;
}

export const Pick = ({name, label, rules, placeholder, units, readonly}: PickProps) => {
    const {control, formState: {errors}} = useFormContext();
    return (
        <View>
            <Text style={formStyles.label}>{label}</Text>
            <Controller
                control={control}
                name={name}
                rules={rules}
                render={({field: {onChange, value}}) => {
                    // 如果是只读模式，直接显示文本
                    if (readonly) {
                        // 从 options 数组中找到当前 value 对应的 label
                        const selectedOption = units.find(opt => opt.value === value);
                        return (
                            <View style={pickerStyles.pickerWrapper}>
                                <Text
                                    style={pickerStyles.readonlyText}>{selectedOption ? selectedOption.label : ''}</Text>
                            </View>
                        );
                    }

                    // 否则，显示正常的 Picker
                    return (
                        <View style={pickerStyles.pickerWrapper}>
                            <Picker
                                selectedValue={value}
                                onValueChange={onChange}
                                style={pickerStyles.picker}
                                mode="dropdown"
                            >
                                <Picker.Item label={placeholder} value=""/>
                                {units.map((opt: any) => (
                                    <Picker.Item key={opt.label} label={opt.label} value={opt.value}/>
                                ))}
                            </Picker>
                        </View>
                    )
                }}
            />
            {errors.unit && (
                <Text style={formStyles.error}>{errors.unit.message?.toString()}</Text>
            )}
        </View>
    )
}

interface ChooserProps {
    name: string,
    label: string,
    rules?: object,
    options: {
        label: string,
        value: string
    }[],
    multi?: boolean
}

export const Chooser = ({name, label, rules, options, multi = false}: ChooserProps) => {
    const {control, formState: {errors}} = useFormContext();
    return (
        <View>
            <Text style={formStyles.label}>{label}</Text>
            <Controller
                control={control}
                name={name}
                rules={rules}
                render={({field: {onChange, value}}) => {
                    // 确保在多选模式下 value 是一个数组
                    const currentValue = multi ? (Array.isArray(value) ? value : []) : value;

                    const handlePress = (itemValue: string) => {
                        if (multi) {
                            // 多选逻辑
                            const newValues = currentValue.includes(itemValue)
                                ? currentValue.filter((v: string) => v !== itemValue) // 移除
                                : [...currentValue, itemValue]; // 添加
                            onChange(newValues);
                        } else {
                            // 单选逻辑
                            onChange(itemValue);
                        }
                    };

                    return (
                        <View style={chooserStyles.radioGroup}>
                            {options.map((item: any) => {
                                const isSelected = multi
                                    ? currentValue.includes(item.value)
                                    : currentValue === item.value;

                                return (
                                    <TouchableOpacity
                                        key={item.value}
                                        style={chooserStyles.radioRow}
                                        onPress={() => handlePress(item.value)}
                                    >
                                        <View style={{width: 20, alignItems: 'center', marginRight: 15,}}>
                                            <Icon
                                                type={"fontawesome"}
                                                name={isSelected ? "check-square-o" : "square-o"}
                                                size={24}
                                                color={isSelected ? "#007AFF" : "#666"}
                                            />
                                        </View>
                                        <Text style={{fontSize: 17}}>{item.label}</Text>
                                    </TouchableOpacity>
                                );
                            })}
                        </View>
                    );
                }}
            />
            {errors[name] && (
                <Text style={formStyles.error}>{errors[name]?.message?.toString()}</Text>
            )}
        </View>
    )
}

interface DatePickerProps {
    name: string,
    label: string,
    rules?: object,
    minimumDate?: string,
    maximumDate?: string,
}

export const DatePicker = ({name, label, rules, minimumDate, maximumDate}: DatePickerProps) => {
    const minDate = minimumDate ? new Date(minimumDate) : undefined;
    const maxDate = maximumDate ? new Date(maximumDate) : undefined;
    const {control} = useFormContext();
    const [showPicker, setShowPicker] = useState<boolean>(false);
    return (
        <Controller
            control={control}
            name={name}
            rules={rules}
            render={({field: {onChange, value}, fieldState: {error}}) => {
                const onDateChange = (event: DateTimePickerEvent, selectedDate?: Date) => {
                    setShowPicker(false); // 无论如何都关闭选择器
                    if (event.type === 'set' && selectedDate) {
                        // 只在用户确认选择时更新表单状态
                        onChange(selectedDate.toISOString().split('T')[0]);
                    }
                };

                return (
                    <View style={datePickerStyles.formItemContainer}>
                        <Text style={datePickerStyles.label}>{label}</Text>
                        <View style={datePickerStyles.dateButton}>
                            <TouchableOpacity onPress={() => setShowPicker(true)}
                                              style={datePickerStyles.dateButtonText}>
                                <Text style={datePickerStyles.dateButtonText}>
                                    {value ? dayjs(value).format("YYYY年 MM月 DD 日") : '请选择日期'}
                                </Text>
                            </TouchableOpacity>
                            {showPicker && (
                                <DateTimePicker
                                    value={value ? new Date(value) : new Date()} // 使用表单中的值，或当前日期作为默认
                                    mode="date"
                                    display="default"
                                    onChange={onDateChange}
                                    minimumDate={minDate}
                                    maximumDate={maxDate}
                                />
                            )}
                        </View>
                        {error && <Text style={datePickerStyles.errorText}>{error.message}</Text>}
                    </View>
                );
            }}
        />
    );
}

export const PlacePicker = ({name, label, mainlandHolder, abroadHolder, rules}: any) => {
    const {control,setValue} = useFormContext();
    const [isAbroad, setIsAbroad] = useState(false);
    const [showSelector, setShowSelector] = useState(false);
    const tranState = (state: boolean) => {
        setValue(name, '');
        setIsAbroad(state);
    }
    return (
        <View>
            <View style={{flexDirection: 'row', alignItems: 'center',marginBottom:-30}}>
                <CheckBox
                    checked={!isAbroad}
                    onPress={() => tranState(false)}
                    title={"国内"}
                    containerStyle={{flex: 1}}
                />
                <CheckBox
                    checked={isAbroad}
                    onPress={() => tranState(true)}
                    title={"国外"}
                    containerStyle={{flex: 1}}
                />
            </View>
            {isAbroad ?
                <Input
                    name={name}
                    label={label}
                    rules={rules}
                    placeholder={abroadHolder}
                /> :
                <Controller
                    control={control}
                    name={name}
                    rules={rules}
                    render={({field: {onChange, value}, fieldState: {error}}) => (
                        <View>
                            <Text style={formStyles.label}>{label}</Text>
                            <TouchableOpacity
                                onPress={() => setShowSelector(true)}
                                style={inputStyles.input}
                            >
                                <Text style={{fontSize: 16}}>
                                    {value || '请选择国内地点'}
                                </Text>
                            </TouchableOpacity>
                            {error && <Text style={formStyles.error}>{error.message}</Text>}

                            <RegionSelector
                                visible={showSelector}
                                onClose={() => setShowSelector(false)}
                                onConfirm={(selectedRegions) => {
                                    const placeString = selectedRegions.map(region => region.name).join(' / ');
                                    onChange(placeString);
                                    setShowSelector(false);
                                }}
                                title="选择前往地点"
                            />
                        </View>
                    )}
                />
            }
        </View>
    )
}

const multiStyles = StyleSheet.create({
    container: {
        marginVertical: 10,
    },
    header: {
        flexDirection: 'row',
        justifyContent: 'space-between',
        alignItems: 'center',
        marginBottom: 10,
    },
    fieldRow: {
        flexDirection: 'row',
        alignItems: 'flex-start',
        marginBottom: 15,
        padding: 10,
        borderWidth: 1,
        borderColor: '#eee',
        borderRadius: 8,
    },
    fieldInputs: {
        flex: 1,
    },
    removeButton: {
        paddingLeft: 10,
        justifyContent: 'center',
        alignItems: 'center',
    }
})

interface MultiProps {
    name: string;
    label: string;
    children: React.ReactElement | React.ReactElement[];
    defaultValues: object;
}

export const Multi = ({name, label, children, defaultValues}: MultiProps) => {
    const {control} = useFormContext();
    const {fields, append, remove} = useFieldArray({
        control,
        name,
    });
    return (
        <View style={multiStyles.container}>
            <View style={multiStyles.header}>
                <Text style={formStyles.label}>{label}</Text>
                <TouchableOpacity onPress={() => append(defaultValues)}>
                    <Icon name="pluscircleo" type="antdesign" size={24} color="#007AFF"/>
                </TouchableOpacity>
            </View>

            {fields.map((field, index) => (
                <View key={field.id} style={multiStyles.fieldRow}>
                    <View style={multiStyles.fieldInputs}>
                        {React.Children.map(children, (child: React.ReactElement) => {
                            if (React.isValidElement(child)) {
                                // 核心：克隆子元素，并注入新的 name prop
                                return React.cloneElement(child, {
                                    ...child.props,
                                    name: `${name}[${index}].${child.props.name}`,
                                    label: child.props.label,
                                });
                            }
                            return child;
                        })}
                    </View>
                    {fields.length > 1 && (
                        <TouchableOpacity onPress={() => remove(index)}>
                            <Icon name="minuscircleo" type="antdesign" size={20} color="#FF3B30"/>
                        </TouchableOpacity>
                    )}
                </View>
            ))}
        </View>
    );
}